package com.example.mywebrtc.util;

import static com.example.mywebrtc.util.Constant.DEFAULT_SDP;

import com.example.mywebrtc.bean.LocalSdpBean;
import com.google.gson.Gson;


import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class SdpUtils {

    // 标准sdp转json
    public static String getSimpleSdp(String stdSdp) {
        LocalSdpBean simSDP = new Gson().fromJson(DEFAULT_SDP, LocalSdpBean.class);
        String[] sdpLines = stdSdp.split("\r\n");
        boolean hasVideo = findLine(sdpLines, "m=", "video") != -1;
        if (hasVideo) {
            int startLine = findLine(sdpLines, "m=video", "");
            int endLine = findLine(sdpLines, "'a=ssrc-group:FID", "");
            int mLineIndex = findLineInRange(sdpLines, startLine, endLine, "a=ice-ufrag:", "");
            String ice_ufrag = sdpLines[mLineIndex].split(":")[1];
            mLineIndex = findLineInRange(sdpLines, startLine, endLine, "a=ice-pwd:", "");
            String ice_pwd = sdpLines[mLineIndex].split(":")[1];
            mLineIndex = findLineInRange(sdpLines, startLine, endLine, "a=fingerprint:", "sha-256");
            String fingerprint = sdpLines[mLineIndex].split("sha-256")[1];
            mLineIndex = findLineInRange(sdpLines,startLine,endLine,"a=rtpmap:", "H264");
            int rtp_pt = Integer.parseInt(sdpLines[mLineIndex].split("a=rtpmap:")[1].split(" ")[0]);
            mLineIndex = findLineInRange(sdpLines, startLine, endLine, "a=fmtp:", "apt=" + rtp_pt);
            int rtx_pt = Integer.parseInt(sdpLines[mLineIndex].split("a=fmtp:")[1].split(" ")[0]);
            simSDP.net_info.ice_ufrag = ice_ufrag;
            simSDP.net_info.ice_pwd = ice_pwd;
            simSDP.encryption.enable_dtls = 1;
            simSDP.encryption.dtls_fingerprint = fingerprint;
            simSDP.rx_caps.video_caps.caps.get(0).codec = "H264";
            simSDP.rx_caps.video_caps.caps.get(0).pt = rtp_pt;
            simSDP.rx_caps.video_caps.caps.get(0).rtx_pt = rtx_pt;
        }
        return new Gson().toJson(simSDP);
    }

    public static String getStdSDP(LocalSdpBean simSdp) {
        String mSessionId = String.valueOf(Math.random()).substring(2, 21);
        int video_count = 1; // TODO
        List<String> lines = new ArrayList(Arrays.asList("v=0",
                "o=- " + mSessionId + " 2 IN IP4 127.0.0.1",
                "s=-",
                "t=0 0"));
        lines.add("a=group:BUNDLE 0");

        String line = "a=msid-semantic: WMS";

        lines.add(line);


        lines.add("m=video 9 UDP/RTP/SAVPF "+ simSdp.rx_caps.video_caps.caps.get(0).pt + " " + simSdp.rx_caps.video_caps.caps.get(0).rtx_pt);
        lines.add("c=IN IP4 0.0.0.0");

        if (simSdp.net_info.candidate_ip.length()>=8 && simSdp.net_info.port >0)
        {
            lines.add("a=rtcp:"+ simSdp.net_info.port +" IN IP4 "+simSdp.net_info.candidate_ip);
            lines.add("a=candidate:3245670104 1 udp 2122260223 "+simSdp.net_info.candidate_ip+" "+ simSdp.net_info.port +" typ host generation 0 network-id 3 network-cost 50");
        }else {
            lines.add("a=rtcp:9 IN IP4 0.0.0.0");
        }
        lines.add("a=ice-ufrag:"+ simSdp.net_info.ice_ufrag);
        lines.add("a=ice-pwd:"+ simSdp.net_info.ice_pwd );
        lines.add("a=ice-options:trickle");
        lines.add("a=sendonly");

        lines.add("a=mid:0");
        lines.add("a=" + simSdp.rx_caps.video_caps.direction); // sendonly

        lines.add("a=fingerprint:sha-256 " + simSdp.encryption.dtls_fingerprint);
        lines.add("a=setup:passive");
        lines.add("a=rtcp-mux");
        lines.add("a=rtpmap:"+ simSdp.rx_caps.video_caps.caps.get(0).pt + " H264/90000");
        lines.add("a=rtcp-fb:"+ simSdp.rx_caps.video_caps.caps.get(0).pt + " ccm fir");
        lines.add("a=rtcp-fb:"+ simSdp.rx_caps.video_caps.caps.get(0).pt + " nack");
        lines.add("a=rtcp-fb:"+ simSdp.rx_caps.video_caps.caps.get(0).pt + " nack pli");
        lines.add("a=fmtp:"+ simSdp.rx_caps.video_caps.caps.get(0).pt + " level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f");
        lines.add("a=rtpmap:"+ simSdp.rx_caps.video_caps.caps.get(0).rtx_pt +" rtx/90000");
        lines.add("a=fmtp:"+ simSdp.rx_caps.video_caps.caps.get(0).rtx_pt +" apt=" + simSdp.rx_caps.video_caps.caps.get(0).pt);

        for (int i = 0; i < video_count; i++)
        {
            String rtp_ssrc = simSdp.tx_stream.stream_list.get(i).ssrc;
            String rtx_ssrc = simSdp.tx_stream.stream_list.get(i).rtx_ssrc;
            lines.add("a=ssrc-group:FID "+ rtp_ssrc + " "+ rtx_ssrc);
            lines.add("a=ssrc:"+ rtp_ssrc + " cname:" + "xxxx");
            lines.add("a=ssrc:"+ rtp_ssrc + " msid:"+ rtp_ssrc + " "+ rtp_ssrc);
            lines.add("a=ssrc:"+ rtp_ssrc + " mslabel:"+ rtp_ssrc);
            lines.add("a=ssrc:"+ rtp_ssrc + " label:"+ rtp_ssrc );
            lines.add("a=ssrc:"+ rtx_ssrc + " cname:"+ "xxxx");
            lines.add("a=ssrc:"+ rtx_ssrc + " msid:"+rtp_ssrc + " "+ rtp_ssrc);
            lines.add("a=ssrc:"+ rtx_ssrc + " mslabel:"+ rtp_ssrc);
            lines.add("a=ssrc:"+ rtx_ssrc + " label:"+ rtp_ssrc);
        }
        lines.add("");
        return String.join("\r\n", lines);
    }

    public static int findLine(String[] sdpLines, String prefix, String subStr) {
        return findLineInRange(sdpLines, 0, -1, prefix, subStr);
    }

    public static int findLineInRange(String[] sdpLines, int startLine, int endLine, String prefix, String subStr) {
        int realEndLine = endLine != -1 ?  endLine : sdpLines.length;
        for (int i = startLine; i < realEndLine; ++i) {
            if (sdpLines[i].indexOf(prefix) == 0) {
                if (!(Objects.equals(subStr, "")) || sdpLines[i].toLowerCase().contains(subStr.toLowerCase())) {
                    return i;
                }
            }
        }
        return -1;
    }
}
